/**
 * @fileOverview Date: 2009-04-6
 * Licensed under Mozilla Public License 1.1 {@link http://www.mozilla.org/MPL/}
 * @author <a href="mailto:jethrolarson@gmail.com">Jethro Larson</a>
 * @version 12
 */
 
/** 
 * Unobtrusively augments the title attribute of html elements 
 * allowing additional formatting and style. Now implemented lazilly in mootools
 * 
 * The only CSS properties required are 
 *   #tooltip{display:none; position: absolute}
 *   Beyond that feel free to go nuts. 
 *
 * @name zenTooltip {@link http://code.google.com/p/zentooltip}
 * @type MooTools
 * @cat Plugins/UI
 * @requires Mootools 1.2.3 or higher {@link http://mootools.com}
 * @example $([elements with tooltip]).zenTooltip()
 * @param {Object} [options] options to configure the tooltip.
 * @param {Number} [options.delay=300] Hover delay before the tooltip is shown 
 * @param {Object} [options.mouseOffset={left: 12, top: 22}] Position of tooltip from cursor 
 * @param {Bool}   [options.useFormatting=true] Whether text formatting will be used. See Tags
 * @param {Object} [options.tags={"#":"h4", "*":"b", "_":"i", "|":"p"}]
 *   {[special character]:[associated tag],[...]}
 *   Special formatting options for the tooltip. The special characters will be 
 *   replaced with the tag indicated. e.g. title="text with *bold*" becomes 
 *   "text with <b>bold</b>" in the tooltip. 
 * @param {String} [options.tooltipClass] Adds a optional class to the tooltip
 */
var zenTooltip = new Class({
  initialize: function(element,options){
    var mousepos = {};
    
    this.options = new Hash({
      "delay": 300,
      "mouseOffset": {"left":11, "top":23},
      "useFormatting": true,
      "tags": {
        "#": "h4",
        "*": "b",
        "_": "i",
        "|": "p"
      },
      "tooltipClass": ""
    }).extend(options);
    
    var that = this;
    this.el = $(element);
    this.tooltip = $("tooltip") || new Element('div',{
      id:"tooltip", 
      html:'<div id="tooltipIWrap"></div>'
    }).inject(document.body).setStyle("display","none");
    function hide(){
      clearTimeout(this.retrieve("timeoutID"));
      $("tooltip").setStyle("display","none");
    }
    function show(){
      $(window).removeEvent("mousemove");
      if(this.options.tooltipClass !="")
        this.tooltip.addClass(this.options.tooltipClass);
      else this.tooltip.removeClass();
      var loc = mousepos;
      loc.left += this.options.mouseOffset.left;
      loc.top += this.options.mouseOffset.top;
      var text = this.el.retrieve("title");
      if(this.options.useFormatting) text = this.transformTitle.call(that,text);
      $("tooltipIWrap").set('html',text);
      this.tooltip.setStyles({"left": loc.left, "top": loc.top}).setStyle("display","block");
      var ttwidth = this.tooltip.getSize().x,
          ttheight = this.tooltip.getSize().y;
      //Bottom Collision
      if(loc.top + ttheight > $(window).getScroll().y + $(window).getSize().y){
        this.tooltip.setStyle("top",loc.top-(ttheight+(this.options.mouseOffset.top*1.5)));
      }
      //Right side collision
      if(loc.left + ttwidth > $(window).getScroll().x + $(window).getSize().x){
        this.tooltip.setStyle("left",loc.left-(ttwidth+this.options.mouseOffset.left));
      }
    }
    this.el.addEvents({
      "mouseenter":function(e){
        //delay
        $(window).addEvent("mousemove",function(e){
          //adapted from {@link http://www.quirksmode.org/js/events_properties.html}
          mousepos.left = e.page.x;
          mousepos.top = e.page.y;
        });
        var timeoutID = setTimeout(show.bind(that), that.options.delay);
        this.store("timeoutID",timeoutID);
      },
      "mouseleave":hide})
      .store("title",this.el.title)
      .removeProperty("title");
    return this;
  },
  transformTitle: function (text){
    $each(this.options.tags,function(val,key){
      var spl = text.split(key),
          out = "";
      for(var i=0;i<spl.length;i++){
        if(i>0)out += "<"+(i%2?"":"/")+val+">";
        out += spl[i];
      }
      text = out;
    });
    return text;
  }
});
